﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICE.Vacations.Entidades;
using ICE.Vacations.Datos.SQL_Manager;
using ICE.Vacations.IIF;


namespace ICE.Vacations.Logica.Solicitudes
{
    public static class RequestManager
    {
        public static int getDiasSolicitados(DateTime fechaInicio, DateTime fechaFin)
        {
            DateTime inicio = fechaInicio;
            int dias = 0;
            DiasLaborales availableDays=Datos.FileManager.EntityToFile.Deserialize<DiasLaborales>(Config.weekDays);

            while (inicio <= fechaFin)
            {
                switch (inicio.DayOfWeek)
                {
                    case DayOfWeek.Monday:
                        {
                            if (availableDays.monday)
                                dias++;
                        } break;
                    case DayOfWeek.Tuesday:
                        {
                            if (availableDays.tuesday)
                                dias++;
                        } break;

                    case DayOfWeek.Wednesday:
                        {
                            if (availableDays.wednesday)
                                dias++;
                        } break;

                    case DayOfWeek.Thursday:
                        {
                            if (availableDays.thursday)
                                dias++;
                        } break;

                    case DayOfWeek.Friday:
                        {
                            if (availableDays.friday)
                                dias++;
                        } break;

                    case DayOfWeek.Saturday:
                        {
                            if (availableDays.saturday)
                                dias++;
                        } break;

                    case DayOfWeek.Sunday:
                        {
                            if (availableDays.sunday)
                                dias++;
                        } break;

                }	          
	            inicio = inicio.AddDays(1);
            }


            return dias-SQLDataClass.diasFeriados(fechaInicio,fechaFin);
        }

        public static void validaciones(Solicitud solicitudXValidar)
        {
            if(solicitudXValidar.username.Equals(""))
                throw new Exception("La cedula del solicitante no puede estar en blanco");

            if (solicitudXValidar.employeeID.Equals(""))
                throw new Exception("La cedula del creador no puede estar en blanco");

            if (solicitudXValidar.fechaInicio == null )
                throw new Exception("La fecha de inicio no puede estar en blanco");

            if (solicitudXValidar.fechaInicio < solicitudXValidar.fechaRegistro)
                throw new Exception("La fecha de inicio no puede ser menor a la fecha de creacion");

            if (solicitudXValidar.fechaFin == null)
                throw new Exception("La fecha de fin no puede estar en blanco");

            if (solicitudXValidar.fechaInicio > solicitudXValidar.fechaFin)
                throw new Exception("La fecha de inicio no puede ser mayor a la fecha final");

            if (solicitudXValidar.diasSolicitados > solicitudXValidar.diasDisponibles)
                throw new Exception("No cuenta con la cantidad de dias disponibles para realizar la solicitud de " + solicitudXValidar.diasSolicitados);

            if (solicitudXValidar.diasSolicitados == 0)
                throw new Exception("Imposible enviar solicitud. Cantidad de dias solicitados: 0");
        }


        private static Solicitud nuevaSolicitud(string user,string cedulaUsuario, string cedulaCreador, int tDiasDisponibles,int diasSolicitados,
             DateTime fechaInicio, DateTime fechaFin,string estado)
            {
                Solicitud solicitud = new Solicitud();
                solicitud.username = cedulaUsuario;
                solicitud.employeeID =cedulaCreador;
                solicitud.fechaRegistro=DateTime.Now;                
                solicitud.diasDisponibles = tDiasDisponibles;
                
                solicitud.fechaInicio=fechaInicio;
                solicitud.fechaFin=fechaFin;
              
                solicitud.diasSolicitados = diasSolicitados;
                solicitud.estado=estado;                

                validaciones(solicitud);
                Recurso rec = Users.UsersManager.getRecurso(user);

                IIFWorkItem infoImage = new IIFWorkItem();
                
                solicitud.objectID=infoImage.CreateWorkitem(solicitud, rec);
               
            
                    solicitud.requestID=SQLDataClass.SQLInsertSolicitud(solicitud);
                
                Entidades.Historico hist=new Historico();
                hist.comentario = "Solicitud ha sido guardada con exito en IIF";
                hist.consultaRRHH = "";
                hist.empleado = solicitud.employeeID;
                hist.estacionIP  = Users.UsersManager.userIP;
                hist.estadoSolicitud = "S";
                hist.idSolicitud = solicitud.requestID;
                hist.notificado = "NULL";
                hist.pdf = "CREATED";
                hist.tipoTransaccion = "INSERT";
                hist.usuario = rec.cedula;
                Datos.SQL_Manager.SQLDataClass.SQLInsertHistorico(hist);
                return solicitud;                
            }

        public static Solicitud guardarSolicitud(string user,string cedulaUsuario, string cedulaCreador, int tDiasDisponibles, int diasSolicitados,
             DateTime fechaInicio, DateTime fechaFin)
        {
            
            return nuevaSolicitud(user,cedulaUsuario, cedulaCreador, tDiasDisponibles, diasSolicitados, fechaInicio, fechaFin,"S");
            
        }




   

        private static bool updateSolicitud(string id,string cedulaUsuario, string cedulaCreador, int tDiasDisponibles,
            int tDiasSolicitados, DateTime fechaInicio, DateTime fechaFin, DateTime fechaGeneracion)
        {
            //si no es el ultimo aprobador solo se cambia el estado en IIF
            //no en la BD
                Solicitud solicitud = new Solicitud();
                solicitud.requestID = id;
                solicitud.username = cedulaUsuario;
                solicitud.employeeID =cedulaCreador;
                solicitud.fechaRegistro = fechaGeneracion;                
                solicitud.diasDisponibles = tDiasDisponibles;
                solicitud.diasSolicitados = tDiasSolicitados;
                solicitud.fechaInicio=fechaInicio;
                solicitud.fechaFin=fechaFin;
                solicitud.estado="S";               
                return SQLDataClass.updateSolicitud(solicitud);
        }
    


        public static bool aprobarSolicitud(string user,Solicitud solicitud, bool aprobado,string comentario="")
        {
            IIFWorkItem iff = new IIFWorkItem();
            Entidades.Historico hist = new Historico();
            Recurso aprobador = Users.UsersManager.getRecurso(user);
            if (solicitud.fechaInicio < DateTime.Now)
            {
                iff.Resolution(solicitud, "D");
                SQLDataClass.UPDATE_State_Solicitud(solicitud.requestID, "D", "NULL");

                hist.comentario = "Resolucion posterior a fecha de inicio";
                hist.consultaRRHH = "";
                hist.empleado = "";
                hist.estacionIP = Users.UsersManager.userIP;
                hist.estadoSolicitud = "D";
                hist.idSolicitud = solicitud.requestID;

                hist.pdf = "NULL";
                hist.tipoTransaccion = "UPDATE";
                hist.usuario = Users.UsersManager.getRecurso(user).cedula;
                Datos.SQL_Manager.SQLDataClass.SQLInsertHistorico(hist);
                throw new Exception("La fecha de inicio no puede ser mayor a la fecha de resolucion");
            }

           

            if (aprobado)
                iff.Resolution(solicitud, "A");
            else
                iff.Resolution(solicitud, "D");


            //cambiar estado en la base de datos como saber si es el ultimo
            int totalAprobadores = SQLDataClass.TotalAprovees(solicitud.employeeID);
            Recurso recurso = SQLDataClass.buscar_empleado(solicitud.employeeID);
            
            string state = "";
            
            switch (totalAprobadores)
            {
                case 1:
                    {
                        if (recurso.aprobador1.Equals(aprobador.cedula))
                        {
                            if (aprobado)
                            {
                                SQLDataClass.UPDATE_State_Solicitud(solicitud.requestID, "A", "NULL");
                                state = "A";
                                hist.notificado = "NULL";
                            }
                            else
                            {
                                SQLDataClass.UPDATE_State_Solicitud(solicitud.requestID, "D", "NULL");
                                state = "D";
                                hist.notificado = "NULL";
                            }

                        }
                    }break;

                case 2:
                    {
                        if (recurso.aprobador2.Equals(aprobador.cedula))
                        {
                            if (aprobado)
                            {
                                SQLDataClass.UPDATE_State_Solicitud(solicitud.requestID, "A", "NULL");
                                state = "A";
                                hist.notificado = "NULL";
                            }
                            else
                            {
                                SQLDataClass.UPDATE_State_Solicitud(solicitud.requestID, "D", "NULL");
                                state = "D";
                                hist.notificado = "NULL";
                            }
                        }
                        else
                        {
                            if (recurso.aprobador1.Equals(aprobador.cedula))
                            {
                                SQLDataClass.UPDATE_State_Solicitud(solicitud.requestID, "P", recurso.aprobador2);
                                state = "P";
                                hist.notificado = recurso.aprobador2;
                            }
                        }
                    } break;

                case 3:
                    {
                        if (recurso.aprobador3.Equals(aprobador.cedula))
                        {
                            if (aprobado)
                            {
                                SQLDataClass.UPDATE_State_Solicitud(solicitud.requestID, "A", "NULL");
                                state = "A";
                                hist.notificado = "NULL";
                            }
                            else
                            {
                                SQLDataClass.UPDATE_State_Solicitud(solicitud.requestID, "D", "NULL");
                                state = "D";
                                hist.notificado = "NULL";
                            }
                        }
                        else
                        {
                            if (recurso.aprobador1.Equals(aprobador.cedula))
                            {
                                SQLDataClass.UPDATE_State_Solicitud(solicitud.requestID, "P", recurso.aprobador2);
                                state = "P";
                                hist.notificado = recurso.aprobador2;
                            }
                            else
                            {
                                SQLDataClass.UPDATE_State_Solicitud(solicitud.requestID, "P", recurso.aprobador3);
                                state = "P";
                                hist.notificado = recurso.aprobador3;
                            }
                        }
                    } break;

                default: { throw new Exception("La consulta arrojo resultados inesperados"); }

            }

            if (comentario.Equals(""))
                hist.comentario = "La resolucion fue tramitada con exito";
            else
                hist.comentario = comentario;
            hist.consultaRRHH = "";
            hist.empleado = "";
            hist.estacionIP  = Users.UsersManager.userIP;
            hist.estadoSolicitud = state ;
            hist.idSolicitud = solicitud.requestID;
            
            hist.pdf = "NULL";
            hist.tipoTransaccion = "UPDATE";
            hist.usuario = aprobador.cedula;
            Datos.SQL_Manager.SQLDataClass.SQLInsertHistorico(hist);

            return true;
        }

        public static bool enviarSolicitud(string user,Solicitud solicitud,string DataPath)
        {
            //subir PDF
            solicitud.estado = "P";
            sendToIIF(user,solicitud,DataPath+"\\"+solicitud.requestID + "_"+solicitud.employeeID);
            Users.UsersManager.deleteCapcha();
            return true;  
        }

        private static bool sendToIIF(string user,Solicitud solicitud,string dataPath)
        {
            //subir PDF

           

            if (solicitud.fechaInicio < DateTime.Now)
                throw new Exception("La fecha de inicio no puede ser mayor a la fecha de envio");

            solicitud.fechaWFL = DateTime.Now;

            IIFWorkItem infoImage = new IIFWorkItem();
            infoImage.AttachPDF_Send(solicitud, dataPath);

            Recurso rec = Users.UsersManager.getRecurso(user);
            Datos.SQL_Manager.SQLDataClass.UPDATE_State_Solicitud (solicitud.requestID, solicitud.estado,rec.aprobador1 );
            
           //solicitud.requestID = SQLDataClass.SQLInsertSolicitud(solicitud);
            Entidades.Historico hist = new Historico();
            hist.comentario = "Solicitud ha sido enviada al WFL";
            hist.consultaRRHH = "";
            hist.empleado = solicitud.employeeID;
            hist.estacionIP = Users.UsersManager.userIP;
            hist.estadoSolicitud = "P";
            hist.idSolicitud = solicitud.requestID;
            hist.notificado = rec.aprobador1;
            hist.pdf = "SENT";
            hist.tipoTransaccion = "S";
            hist.usuario = rec.cedula;
            Datos.SQL_Manager.SQLDataClass.SQLInsertHistorico(hist);

            return true;
        }




        public static bool deleteSolicitud(string id)
        {
            return SQLDataClass.deleteSolicitud(id);
        }
        private static List<Solicitud> solicitudes = new List<Solicitud>();
        public static List<Solicitud> getSolicitudes()
        {
            return solicitudes;
        }
        public static List<Solicitud> consultarSolicitud(string user)
        {
            solicitudes=SQLDataClass.consultarSolicitud(Users.UsersManager.getRecurso(user).cedula);
            return solicitudes;
        }

        public static List<Solicitud> consultarSolicitud(string user,string campo,string valor,string nombre="")
        {
            solicitudes=SQLDataClass.consultarSolicitud(campo, valor, Users.UsersManager.getRecurso(user).cedula,nombre);
            return solicitudes;
        }


        /*public static List<Solicitud> consultarSolicitudesSalvadas()
        {
            return SQLDataClass.consultarSolicitud(Users.UsersManager.getRecurso().cedula);
        }


        public static List<Solicitud> consultarSolicitudesSalvadas(string campo, string valor)
        {
            return SQLDataClass.consultarSolicitud(campo, valor, Users.UsersManager.getRecurso().cedula);
        }*/



    }
}
